<!--
  MessageBox组件，这个组件放在q-app这个div下方，整个程序就一个
-->
<template>
  <q-dialog v-model="isShowMessageBox" :persistent="checkIfNeedPersistent" @hide="onDialogClosed" transition-show="none"
    transition-hide="none" @keyup.enter="onEnterPress">
    <q-card style="min-width: 300px;">
      <div :class="getColor('bg-')" style="height:8px" v-if="getColor('')!==''" />
      <q-card-section>
        <q-icon class="float-left q-mr-md" :name="iconToShow" :color="getColor('')" size="58px" v-if="icon!=='none'" />
        <div class="text-h6">{{caption}}</div>
        <div>{{text}}</div>
      </q-card-section>
      <q-separator v-if="buttons!=='none'" />
      <q-card-actions align="right" v-if="buttons!=='none'">
        <q-btn ref="btnOk" color="primary" @click="onButtonClicked('ok')" v-if="checkIfShowOk" no-caps
          :disable="activating !== ''" :loading="activating==='ok'">{{$t('确定')}}
          <template v-slot:loading>
            <q-spinner />&nbsp;{{$t('确定')}}
          </template>
        </q-btn>
        <q-btn color="primary" @click="onButtonClicked('yes')" v-if="checkIfShowYesOrNo" :disable="activating !== ''" no-caps
          :loading="activating==='yes'">{{$t('是')}}
          <template v-slot:loading>
            <q-spinner />&nbsp;{{$t('是')}}
          </template>
        </q-btn>
        <q-btn color="red-10" @click="onButtonClicked('no')" v-if="checkIfShowYesOrNo" :disable="activating !== ''" no-caps
          :loading="activating==='no'">{{$t('否')}}
          <template v-slot:loading>
            <q-spinner />&nbsp;{{$t('否')}}
          </template>
        </q-btn>
        <q-btn unelevated color="primary" @click="onButtonClicked('cancel')" v-if="checkIfShowCancel" no-caps
          :disable="activating !== '' && disableCancelCloseBtnWhenWorking" outline>{{$t('取消')}}
        </q-btn>
        <q-btn unelevated color="primary" @click="onButtonClicked('close')" v-if="checkIfShowClose" no-caps
          :disable="activating !== '' && disableCancelCloseBtnWhenWorking" outline>{{$t('关闭')}}
        </q-btn>
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>
<script lang="ts">
export default {
  name: 'njtMessageBox'
}
</script>
<script lang="ts" setup>
import {ref, computed} from 'vue'
import {MessageBoxParams} from '../defs/comm'

// MessageBox是否显示
const isShowMessageBox = ref(false)
//内部用，Promise回调方法
let promiseResolve: ((btn: string) => void) | null = null
// 回调方法 (使用Promise方式之外的另一种选项)
let callback: ((btn: string) => void) | null = null
//内部用，表示按在了哪个按钮上
let clickedOnButton = ''

//标题
const caption = ref('')
//内容
const text = ref('')
//呈现的按钮
const buttons = ref('')
//呈现的图标
const icon = ref('')
// 是否延迟关闭，如果是，点yes，ok之后，会马上调用回调方法，但对话框不会马上关闭，活动指示器会出现
const delayClose = ref(false)
// 活动指示器状态，可能是yes，ok，表示活动指示器出现在哪个按钮上，空字符串表示没有活动指示器
const activating = ref('')
// 在工作状态时候，将Cancel和Close按钮禁用
const disableCancelCloseBtnWhenWorking = ref(true)
// OK按钮是否显示
const checkIfShowOk = computed(() => buttons.value === 'ok' || buttons.value === 'okcancel')
// Cancel按钮是否显示
const checkIfShowCancel = computed(() => buttons.value === 'okcancel' || buttons.value === 'yesnocancel')
// Yes和No按钮是否显示
const checkIfShowYesOrNo = computed(() => buttons.value === 'yesno' || buttons.value === 'yesnocancel')
// Close按钮是否显示
const checkIfShowClose = computed(() => buttons.value === 'close')
// 对话框的persistent状态
const checkIfNeedPersistent = computed(() => !(
  buttons.value === 'yesnocancel' ||
  buttons.value === 'okcancel' ||
  buttons.value === 'none' ||
  buttons.value === 'close'
) || activating.value !== '')
// 显示的图标
const iconToShow = computed(() => {
  switch (icon.value) {
    case 'error':
      return 'cancel'
    case 'information':
      return 'info'
    case 'question':
      return 'help'
    case 'warning':
      return 'warning'
    case 'reqerr':
      return 'block'
    case 'succeeded':
      return 'check_circle'
  }
  return ''
})
//获取颜色样式的方法
const getColor = function (prefix: string) {
  switch (icon.value) {
    case 'error':
    case 'reqerr':
      return prefix + 'negative'
    case 'information':
    case 'question':
      return prefix + 'info'
    case 'warning':
      return prefix + 'warning'
    case 'succeeded':
      return prefix + 'positive'
  }
  return ''
}
// 非延迟关闭情况下，对话框关闭，传回用户所点击的按钮
const onDialogClosed = function () {
  if (activating.value === '' && promiseResolve != null) {
    promiseResolve(clickedOnButton)
  }
}
// 敲回车键
const onEnterPress = function () {
  if (buttons.value === 'ok' || buttons.value === 'okcancel') {
    if (onButtonClicked)
      onButtonClicked('ok')
  } else if (buttons.value === 'yesno' || buttons.value === 'yesnocancel') {
    onButtonClicked('yes')
  } else if (buttons.value === 'close') {
    onButtonClicked('close')
  } else {
    onButtonClicked('none')
  }
}
// 按钮点击
const onButtonClicked = function (buttonName: string) {
  if (callback) {
    callback(buttonName)
  }
  clickedOnButton = buttonName
  if (delayClose.value && (buttonName === 'ok' || buttonName === 'yes')) {
    activating.value = buttonName
    if (promiseResolve != null) {
      promiseResolve(clickedOnButton)
    }
    return
  }
  isShowMessageBox.value = false
}
// 直接关闭对话框
const hideMsgBox = function () {
  isShowMessageBox.value = false
}
// 弹出messageBox,并创建promise对象
const showMsgBox = function (param: MessageBoxParams): Promise<string> {
  // 阻止重复弹出
  if (isShowMessageBox.value && activating.value === '') {
    return Promise.resolve('cancel')
  }
  isShowMessageBox.value = false
  activating.value = ''
  // 默认值
  let defaultParam: MessageBoxParams = {
    // 标题
    caption: '',
    // 弹框内容
    text: '',
    // 按钮类型: Ok, OkCancel, YesNo, YesNoCancel, Close
    buttons: 'none',
    // 图标类型: None, Error, ReqErr, Information, Question, Warning, Succeeded
    icon: 'none',
    // 是否延迟关闭，如果true，则在按下yes，no，ok之后显示活动指示器，而不是关闭
    delayClose: false,
    // 在工作状态时候，将Cancel和Close按钮禁用
    disableCancelCloseBtnWhenWorking: true,
    // 回调方法 (使用Promise方式之外的另一种选项)
    callback: null
  }
  let thisParam = Object.assign(defaultParam, param)

  caption.value = thisParam.caption as string
  text.value = thisParam.text as string
  buttons.value = (thisParam.buttons as string).toLowerCase()
  icon.value = (thisParam.icon as string).toLowerCase()
  clickedOnButton = 'cancel' // 默认按中的就是cancel按钮
  delayClose.value = thisParam.delayClose as boolean
  disableCancelCloseBtnWhenWorking.value = thisParam.disableCancelCloseBtnWhenWorking as boolean
  isShowMessageBox.value = true
  callback = thisParam.callback as (((btn: string) => void) | null)
  return new Promise((resolve) => {
    promiseResolve = resolve
  })
}

$f.ui.messageBox = showMsgBox
$f.ui.closeMsgBox = hideMsgBox

</script>
